let _uid = Date.now() + Math.floor(Math.random() * 1000) + 1000000;
const connectedSocketDict = {};
const adminSocketDict = {};
const NewsService = require('../service/News').model;
const CommentService = require('../service/Comment').model;

module.exports = function(socket) {
  let _socketId = _uid++;
  let newsId = null;
  let isAdmin = false;
  socket.socketId = _socketId;
  socket.on('adminLogin', function() {
    // TODO: auth.
    adminSocketDict[_socketId] = socket;
    isAdmin = true;
  });
  socket.on('viewingNews', function(payload) {
    setViewingNewsId(payload._id);
  });
  socket.on('createComment', async function({ _id, data}) {
    setViewingNewsId(_id);
    const { news, resultedComment } = await NewsService.createComment(newsId, _socketId, data);
    socket.emit('createCommentSucceed');
    for (let socket of (connectedSocketDict[newsId] || [])) {
      socket.emit('appendComment', { _id, socketId: _socketId, data: resultedComment });
    }
    for (let _socketId in adminSocketDict) {
      let socket = adminSocketDict[_socketId];
      socket.emit('watchComment', { _id, socketId: _socketId, data: resultedComment });
    }

  });
  socket.on('verifyComment', async function({ _id, data }) {
    if (!isAdmin) {
      // TODO: auth.
    }
    const resultedComment = await CommentService.verifyComment(data.commentId, data.state);
    socket.emit('verifyCommentSucceed');
    const newsId = _id;
    for (let socket of (connectedSocketDict[newsId] || [])) {
      socket.emit('updateComment', { _id, socketId: _socketId, data: resultedComment });
    }
    for (let _socketId in adminSocketDict) {
      let socket = adminSocketDict[_socketId];
      socket.emit('updateComment', { _id, socketId: _socketId, data: resultedComment });
    }
  });
  socket.on('disconnect', function() {
    console.log('socket disconnect\n\tnewsId: ', newsId, '\n\tsocketId: ', _socketId);
    cancelViewingNews();
    if (isAdmin) {
      isAdmin = false;
      delete adminSocketDict[_socketId];
    }
  });
  socket.on('reconnect', function() {
    init();
  });
  function setViewingNewsId(_id) {
    if (newsId == _id) {
      return;
    }
    if (null != newsId) {
      cancelViewingNews();
    }
    newsId = _id;
    connectedSocketDict[newsId] = connectedSocketDict[newsId] || [];
    connectedSocketDict[newsId].push(socket);
  }
  function cancelViewingNews() {
    if (null != newsId) {
      let socketList = connectedSocketDict[newsId] || [];
      let index = socketList.indexOf(socket);
      socketList.splice(index, 1);
      if (socketList.length == 0) {
        delete connectedSocketDict[newsId];
      }
      newsId = null;
    }
  }
  function init() {
    socket.emit('setId', {
      data: _socketId,
    });
    socket.emit('newsIdRequired');
  }
  init();
};